<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2022/02/24} {11:21} 
 */

namespace wanghua\general_utility_tools_php\api;


use wanghua\general_utility_tools_php\mysql\lib\Table;
use wanghua\general_utility_tools_php\tool\Tools;

class Api extends BaseLibApi
{
    private $apidir = '';
    private $namespace = 'app\api\controller';

    private $table_obj = null;

    //一维数组
    private $functions_arr = [];//要创建的初始方法

    public function __construct()
    {
        //默认api目录
        $this->apidir = Tools::get_root_path().'application/api/controller/';
        if(!$this->table_obj)
            $this->table_obj = new Table();
    }

    /**
     * desc：api目录
     * author：wh
     * @param string $dir api创建目录，格式必须按照例子填写 eg: application/api/controller/
     */
    function setapidir(string $dir){
        $this->apidir = $dir;
        $nsp = str_replace('application','app',substr($dir,0,strlen($dir)-2));
        $this->namespace = str_replace('/','\\',$nsp);
    }

    /**
     * desc：替换表前缀
     * author：wh
     * @param $tablename
     * @return false|string
     */
    function replaceTablePrefix($tablename){
        $prefix = config('database.prefix');
        if($prefix){
            return substr($tablename,strlen($prefix));
        }
        $tmp_prefix = 't_';
        if(false !== strpos($tablename,$tmp_prefix)){
            return substr($tablename,strlen($tmp_prefix));
        }
        return $tablename;
    }

    /**
     * desc：设置方法名称
     *
     * author：wh
     * @param array $functions_arr
     */
    function setApiFunctionsName(array $functions_arr){
        $this->functions_arr = array_merge($functions_arr,$this->functions_arr);
    }

    /**
     * desc：动态创建方法
     *
     * author：wh
     */
    private function syncCreateFunction(array $func_name_arr){
        $code = '';
        foreach ($func_name_arr as $func_name=>$func_remark){ //接口方法公共代码模块
            $commonFunctionCodeModule = $this->commonFunctionCodeModule($func_remark);
            $code .= <<<EOF

    /**
     * desc：{$func_remark}
     * 
     * author：
     */
    function {$func_name}(){
    {$commonFunctionCodeModule}
    }
EOF;
        }
        return $code;
    }

    /**
     * desc：创建查询接口的代码体
     *
     * 本接口只针对简单查询逻辑
     *
     * and
     * like%，%like%,
     * >, <, >=, <=, !=
     * between
     * in
     *
     * author：wh
     * @param array $select_in_params eg:
     * [
     *  'gameid'=>['and'],
     *  'nickname'=>['like%'],
     *  'reg_time'=>['between'],//时间区间查询
     *  'audit_time'=>['2015-01-3','eq'],//时间区间查询
     * ]
     *
     */
    function setQueryCodeBody(array $select_in_params){
        $code = '';

        return $code;
    }

    /**
     * desc：写入查询接口的代码体
     *
     * author：wh
     * @param array $insert_params
     * @return string
     */
    function setInsertCodeBody(array $insert_params){
        $code = '';

        return $code;
    }

    /**
     * desc：快速构建api代码
     *
     * 本方法不验证接口名称是否重复
     *
     * author：wh
     * @param string $tablename 数据表名称
     * @param array $func_name_arr 方法名称数组 eg:['getData'=>'获取数据','function_aaa'=>'function_注释aaa']
     */
    function buildApi(string $tablename, array $func_name_arr){
        //deal table name
        $tablename = $this->replaceTablePrefix($tablename);

        //基础 start
        //create base controller
        $this->buildBaseApiPublicController();//开放控制器
        $this->buildBaseApiAuthController();//权限控制器
        $this->errController();//错误控制器
        //基础 end

        //接口类名
        $classname = ucfirst(Tools::convertUnderLine($tablename));
        //接口注释
        $comment = $this->table_obj->getTableComment($tablename);

        //批量构建方法代码
        $build_functions_code = $this->syncCreateFunction($func_name_arr);

        //PHP文件名，不含物理路径
        $file_name = $classname.$this->ext();

        //PHP文件路径和文件名
        $php_file = $this->apidir.$file_name;

        if(file_exists($php_file)){
            //追加代码
            //读取并删除最后的“}”
            $php_code_str = file_get_contents($php_file);
            $sub_php_code_str = mb_substr($php_code_str,0,mb_strlen($php_code_str)-2);
            //追加新的代码
            $sub_php_code_str .= $build_functions_code ."\n }";
            //清空代码
            file_put_contents($php_file,'');
            //追加
            $this->createFileExists($php_file,$sub_php_code_str);
        }else{
            //创建代码文件
            $use_tpl = $this->useTpl();
            $php = <<<EOF
<?php

namespace {$this->namespace};
{$use_tpl}

/**
 * {$comment}
 * Class {$classname}
 * @package {$this->namespace}
 */
class {$classname} extends BaseApiPublicController
{

    

    {$build_functions_code}

}
EOF;

            $this->createDir($this->apidir);


            $this->createFile($php_file,$php);
        }
    }

    /**
     * desc：公共方法模块
     *
     * author：wh
     * @param $comment
     * @return string
     */
    private function commonFunctionCodeModule($comment){
        $php = <<<EOF
        try {
            Tools::log_to_write_txt(['title'=>'{$comment},__IN：','INPUT'=>input()]);
            //region 校验区 start
            
            //endregion 校验区 end


            
            
            //region 业务逻辑区 start
            
            //endregion 业务逻辑区 end
            
            
            
            
            //响应结果处理
            Tools::log_to_write_txt(['title'=>'{$comment},__OUT：','OUTPUT'=>[]]);
            return json(Tools::set_res(200,'ok'));
        }catch (\Exception \$e){
            Tools::log_to_write_txt([
                'error'=>'{$comment},API异常。'.\$e->getMessage(),
                '入参'=>input(),
                'error_info'=>\$e->getTraceAsString()
            ]);
            return json(Tools::set_res(500,'系统繁忙'));
        }
EOF;

        return $php;
    }

    /**
     * desc：api基础开放控制器
     *
     * 如果存在则不创建
     *
     * author：wh
     */
    private function buildBaseApiPublicController(){
        $file_name = 'BaseApiPublicController';
        $php = <<<EOF
<?php

namespace {$this->namespace};

use think\Controller;


/**
 * desc：api基础开放架构
 * 
 * 所有开放接口继承此父类
 * 
 * author：
 */
class {$file_name} extends Controller
{
    
}
EOF;

        $php_file = $this->apidir.$file_name.$this->ext();

        $this->createDir($this->apidir);

        $this->createFile($php_file,$php);
    }

    /**
     * desc：api基础权限控制器
     *
     * 如果存在则不创建
     *
     * author：wh
     */
    private function buildBaseApiAuthController(){
        $file_name = 'BaseApiAuthController';
        $php = <<<EOF
<?php

namespace {$this->namespace};

use think\Controller;


/**
 * desc：api基础权限架构
 * 
 * 所有权限接口继承此父类
 * 
 * author：
 */
class {$file_name} extends Controller
{
    
}
EOF;

        $php_file = $this->apidir.$file_name.$this->ext();

        $this->createDir($this->apidir);

        $this->createFile($php_file,$php);
    }

    /**
     * desc：api底层基础控制器架构
     *
     * [按需创建][可单独调用]
     *
     * 如果存在则不创建
     *
     * author：wh
     */
    function buildBaseApiController(){
        $file_name = 'BaseApiController';
        $php = <<<EOF
<?php

namespace {$this->namespace};

use think\Controller;


/**
 * desc：api底层基础控制器架构
 * 
 * author：
 */
class {$file_name} extends Controller
{
    
    
}
EOF;

        $php_file = $this->apidir.$file_name.$this->ext();

        $this->createDir($this->apidir);

        $this->createFile($php_file,$php);
    }

    /**
     * desc：use模块
     *
     * author：wh
     * @return string
     */
    private function useTpl(){
        $php = <<<EOF
use wanghua\general_utility_tools_php\\tool\Tools;
EOF;
        return $php;
    }

    /**
     * desc：错误控制器
     *
     * author：wh
     */
    function errController(){
        $file_name = 'Err';
        $php = <<<EOF
<?php

namespace {$this->namespace};


use wanghua\general_utility_tools_php\\framework\\base\PublicController;
use wanghua\general_utility_tools_php\\tool\Tools;


/**
 *
 * 错误(异常)中转架构
 *
 * Class Err
 * @package app\index\controller
 */
class {$file_name} extends BaseApiPublicController
{
    /**
     * desc：校验失败中转
     *
     * 场景：内网端口验证未通过时跳转；
     *
     * author：wh
     * @return \\think\\response\\Json
     */
    function checkfailed(){

        return json(Tools::set_res(500,'Permission denied',input()));
    }
}
EOF;

        $php_file = $this->apidir.$file_name.$this->ext();

        $this->createDir($this->apidir);

        $this->createFile($php_file,$php);
    }
}